{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# qGANs for Loading Random Distributions\n",
    "\n",
    "Given $k$-dimensional data samples, we employ a quantum Generative Adversarial Network (qGAN) to learn the data's underlying random distribution and to load it directly into a quantum state:\n",
    "\n",
    "$$\\big| g_{\\theta}\\rangle = \\sum_{j=0}^{2^n-1} \\sqrt{p_{\\theta}^{j}}\\big| j \\rangle$$\n",
    "\n",
    "where $p_{\\theta}^{j}$ describe the occurrence probabilities of the basis states $\\big| j\\rangle$. \n",
    "\n",
    "The aim of the qGAN training is to generate a state $\\big| g_{\\theta}\\rangle$ where $p_{\\theta}^{j}$, for $j\\in \\left\\{0, \\ldots, {2^n-1} \\right\\}$, describe a probability distribution that is close to the distribution underlying the training data $X=\\left\\{x^0, \\ldots, x^{k-1} \\right\\}$.\n",
    "\n",
    "For further details please refer to [Quantum Generative Adversarial Networks for Learning and Loading Random Distributions](https://arxiv.org/abs/1904.00043) _Zoufal, Lucchi, Woerner_ \\[2019\\].\n",
    "\n",
    "For an example of how to use a trained qGAN in an application, the pricing of financial derivatives, please see the\n",
    "[Option Pricing with qGANs](../finance/10_qgan_option_pricing.ipynb) tutorial."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "seed = 71\n",
    "np.random.seed = seed\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from qiskit import QuantumRegister, QuantumCircuit, BasicAer\n",
    "from qiskit.circuit.library import TwoLocal, UniformDistribution\n",
    "\n",
    "from qiskit.aqua import QuantumInstance, aqua_globals\n",
    "from qiskit.aqua.algorithms import QGAN\n",
    "from qiskit.aqua.components.neural_networks import NumPyDiscriminator\n",
    "\n",
    "aqua_globals.random_seed = seed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load the Training Data\n",
    "\n",
    "First, we need to load the $k$-dimensional training data samples (here k=1).\n",
    "\n",
    "Next, the data resolution is set, i.e. the min/max data values and the number of qubits used to represent each data dimension."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Number training data samples\n",
    "N = 1000 \n",
    "\n",
    "# Load data samples from log-normal distribution with mean=1 and standard deviation=1\n",
    "mu = 1\n",
    "sigma = 1\n",
    "real_data = np.random.lognormal(mean=mu, sigma=sigma, size=N)\n",
    "\n",
    "# Set the data resolution\n",
    "# Set upper and lower data values as list of k min/max data values [[min_0,max_0],...,[min_k-1,max_k-1]]\n",
    "bounds = np.array([0., 3.]) \n",
    "# Set number of qubits per data dimension as list of k qubit values[#q_0,...,#q_k-1]\n",
    "num_qubits = [2]\n",
    "k = len(num_qubits)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initialize the qGAN\n",
    "\n",
    "The qGAN consists of a quantum generator $G_{\\theta}$, a variational quantum circuit, and a classical discriminator $D_{\\phi}$, a neural network.\n",
    "\n",
    "To implement the quantum generator, we choose a depth-$1$ variational form that implements $R_Y$ rotations and $CZ$ gates which takes a uniform distribution as an input state. Notably, for $k>1$ the generator's parameters must be chosen carefully. For example, the circuit depth should be $>1$ because higher circuit depths enable the representation of more complex structures.\n",
    "\n",
    "The classical discriminator used here is based on a neural network implementation using NumPy. There is also a discriminator based on PyTorch which is not installed by default when installing Qiskit - see [Optional Install](https://github.com/Qiskit/qiskit-aqua#optional-installs) for more information.\n",
    "\n",
    "Here, both networks are updated with the ADAM optimization algorithm (ADAM is qGAN optimizer default)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set number of training epochs\n",
    "# Note: The algorithm's runtime can be shortened by reducing the number of training epochs.\n",
    "num_epochs = 10\n",
    "# Batch size\n",
    "batch_size = 100\n",
    "\n",
    " # Initialize qGAN\n",
    "qgan = QGAN(real_data, bounds, num_qubits, batch_size, num_epochs, snapshot_dir=None)\n",
    "qgan.seed = 1\n",
    "# Set quantum instance to run the quantum generator\n",
    "quantum_instance = QuantumInstance(backend=BasicAer.get_backend('statevector_simulator'),\n",
    "                                   seed_transpiler=seed, seed_simulator=seed)\n",
    "\n",
    "# Set entangler map\n",
    "entangler_map = [[0, 1]]\n",
    "\n",
    "\n",
    "# Set an initial state for the generator circuit\n",
    "init_dist = UniformDistribution(sum(num_qubits))\n",
    "\n",
    "# Set the ansatz circuit\n",
    "var_form = TwoLocal(int(np.sum(num_qubits)), 'ry', 'cz', entanglement=entangler_map, reps=1)\n",
    "\n",
    "# Set generator's initial parameters - in order to reduce the training time and hence the \n",
    "# total running time for this notebook\n",
    "init_params = [3., 1., 0.6, 1.6]\n",
    "\n",
    "# You can increase the number of training epochs and use random initial parameters.\n",
    "# init_params = np.random.rand(var_form.num_parameters_settable) * 2 * np.pi\n",
    "\n",
    "# Set generator circuit by adding the initial distribution infront of the ansatz\n",
    "g_circuit = var_form.compose(init_dist, front=True)\n",
    "\n",
    "# Set quantum generator\n",
    "qgan.set_generator(generator_circuit=g_circuit, generator_init_params=init_params)\n",
    "# The parameters have an order issue that following is a temp. workaround\n",
    "qgan._generator._free_parameters = sorted(g_circuit.parameters, key=lambda p: p.name)\n",
    "# Set classical discriminator neural network\n",
    "discriminator = NumPyDiscriminator(len(num_qubits))\n",
    "qgan.set_discriminator(discriminator)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run the qGAN Training\n",
    "\n",
    "During the training the discriminator's and the generator's parameters are updated alternately w.r.t the following loss functions:\n",
    "$$ L_G\\left(\\phi, \\theta\\right) = -\\frac{1}{m}\\sum\\limits_{l=1}^{m}\\left[\\log\\left(D_{\\phi}\\left(g^{l}\\right)\\right)\\right] $$\n",
    "and\n",
    "$$  L_D\\left(\\phi, \\theta\\right) =\n",
    "\t\\frac{1}{m}\\sum\\limits_{l=1}^{m}\\left[\\log D_{\\phi}\\left(x^{l}\\right) + \\log\\left(1-D_{\\phi}\\left(g^{l}\\right)\\right)\\right], $$\n",
    "with $m$ denoting the batch size and $g^l$ describing the data samples generated by the quantum generator.\n",
    "\n",
    "Please note that the training, for the purpose of this notebook, has been kept briefer by the selection of a known initial point (`init_params`). Without such prior knowledge be aware training may take some while."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run qGAN\n",
    "result = qgan.run(quantum_instance)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training results:\n",
      "  params_d : [ 0.03657504  0.61055093 -0.48069924 ... -0.1663881  -0.20141375\n",
      " -0.08574845]\n",
      "  params_g : [2.95411419 0.95407814 0.55406927 1.64597496]\n",
      "  loss_d : 0.6925\n",
      "  loss_g : [0.7279]\n",
      "  rel_entr : 0.1655\n"
     ]
    }
   ],
   "source": [
    "print('Training results:')\n",
    "for key, value in result.items():\n",
    "    print(f'  {key} : {value}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Training Progress & Outcome\n",
    "\n",
    "Now, we plot the evolution of the generator's and the discriminator's loss functions during the training, as well as the progress in the relative entropy between the trained and the target distribution.\n",
    "\n",
    "Finally, we also compare the cumulative distribution function (CDF) of the trained distribution to the CDF of the target distribution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f66f9e4bd68>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot progress w.r.t the generator's and the discriminator's loss function\n",
    "t_steps = np.arange(num_epochs)\n",
    "plt.figure(figsize=(6,5))\n",
    "plt.title(\"Progress in the loss function\")\n",
    "plt.plot(t_steps, qgan.g_loss, label='Generator loss function', color='mediumvioletred', linewidth=2)\n",
    "plt.plot(t_steps, qgan.d_loss, label='Discriminator loss function', color='rebeccapurple', linewidth=2)\n",
    "plt.grid()\n",
    "plt.legend(loc='best')\n",
    "plt.xlabel('time steps')\n",
    "plt.ylabel('loss')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f66f9e4d390>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot progress w.r.t relative entropy\n",
    "plt.figure(figsize=(6,5))\n",
    "plt.title('Relative Entropy')\n",
    "plt.plot(np.linspace(0, num_epochs, len(qgan.rel_entr)), qgan.rel_entr, color='mediumblue', lw=4, ls=':')\n",
    "plt.grid()\n",
    "plt.xlabel('time steps')\n",
    "plt.ylabel('relative entropy')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "tags": [
     "nbsphinx-thumbnail"
    ]
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f66f9cefa58>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Plot the CDF of the resulting distribution against the target distribution, i.e. log-normal\n",
    "log_normal = np.random.lognormal(mean=1, sigma=1, size=100000)\n",
    "log_normal = np.round(log_normal)\n",
    "log_normal = log_normal[log_normal <= bounds[1]]\n",
    "temp = []\n",
    "for i in range(int(bounds[1] + 1)):\n",
    "    temp += [np.sum(log_normal==i)]\n",
    "log_normal = np.array(temp / sum(temp))\n",
    "\n",
    "plt.figure(figsize=(6,5))\n",
    "plt.title('CDF (Cumulative Distribution Function)')\n",
    "samples_g, prob_g = qgan.generator.get_output(qgan.quantum_instance, shots=10000)\n",
    "samples_g = np.array(samples_g)\n",
    "samples_g = samples_g.flatten()\n",
    "num_bins = len(prob_g)\n",
    "plt.bar(samples_g,  np.cumsum(prob_g), color='royalblue', width= 0.8, label='simulation')\n",
    "plt.plot( np.cumsum(log_normal),'-o', label='log-normal', color='deepskyblue', linewidth=4, markersize=12)\n",
    "plt.xticks(np.arange(min(samples_g), max(samples_g)+1, 1.0))\n",
    "plt.grid()\n",
    "plt.xlabel('x')\n",
    "plt.ylabel('p(x)')\n",
    "plt.legend(loc='best')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-22T01:49:13.439275Z",
     "start_time": "2019-08-22T01:49:13.430311Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<h3>Version Information</h3><table><tr><th>Qiskit Software</th><th>Version</th></tr><tr><td>Qiskit</td><td>0.23.1</td></tr><tr><td>Terra</td><td>0.16.1</td></tr><tr><td>Aer</td><td>0.7.1</td></tr><tr><td>Ignis</td><td>0.5.1</td></tr><tr><td>Aqua</td><td>0.8.1</td></tr><tr><td>IBM Q Provider</td><td>0.11.1</td></tr><tr><th>System information</th></tr><tr><td>Python</td><td>3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 13:09:58) \n",
       "[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]</td></tr><tr><td>OS</td><td>Linux</td></tr><tr><td>CPUs</td><td>1</td></tr><tr><td>Memory (Gb)</td><td>5.827335357666016</td></tr><tr><td colspan='2'>Tue Nov 17 12:56:05 2020 EST</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style='width: 100%; background-color:#d5d9e0;padding-left: 10px; padding-bottom: 10px; padding-right: 10px; padding-top: 5px'><h3>This code is a part of Qiskit</h3><p>&copy; Copyright IBM 2017, 2020.</p><p>This code is licensed under the Apache License, Version 2.0. You may<br>obtain a copy of this license in the LICENSE.txt file in the root directory<br> of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.<p>Any modifications or derivative works of this code must retain this<br>copyright notice, and modified files need to carry a notice indicating<br>that they have been altered from the originals.</p></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import qiskit.tools.jupyter\n",
    "%qiskit_version_table\n",
    "%qiskit_copyright"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
